/**
 * @file testThread.c
 * @brief
 * @author  xiaowine (xiaowine@sina.cn)
 * @version 01.00
 * @date    2021-05-17
 *
 * @copyright Copyright (c) {2020}  xiaowine
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2021-05-17 <td>1.0     <td>wangh     <td>内容
 * </table>
 * ******************************************************************
 * *                   .::::
 * *                 .::::::::
 * *                ::::::::::
 * *             ..:::::::::::
 * *          '::::::::::::
 * *            .:::::::::
 * *       '::::::::::::::..        女神助攻,流量冲天
 * *            ..::::::::::::.     永不宕机,代码无bug
 * *          ``:::::::::::::::
 * *           ::::``:::::::::'        .:::
 * *          ::::'   ':::::'       .::::::::
 * *        .::::'      ::::     .:::::::'::::
 * *       .:::'       :::::  .:::::::::' ':::::
 * *      .::'        :::::.:::::::::'      ':::::
 * *     .::'         ::::::::::::::'         ``::::
 * * ...:::           ::::::::::::'              ``::
 * *```` ':.          ':::::::::'                  ::::.
 * *                   '.:::::'                    ':'````.
 * ******************************************************************
 */

/* Private includes ----------------------------------------------------------*/
#include "cmsis_os.h"  // CMSIS RTOS header file
#include "stm32f1xx_hal.h"
#include <stdio.h>
#include <string.h>
#include "userType.h"
#define osObjectsPublic  // define objects in main module
#include "osObjects.h"   // RTOS object definitions
#include "modbus_host.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define NO1(x) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, (x));  // NO1
#define NO2(x) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, (x));  // NO2
#define NO3(x) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, (x));  // NO3
#define NO4(x) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (x));  // NO4
#define NO5(x) HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, (x));  // NO5
#define NO6(x) HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, (x));  // NO6
#define NO7(x) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, (x));  // NO7
#define NO8(x) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, (x));  // NO8

#define KEY0Trg keyTrg[0].bits.b0
#define KEY1Trg keyTrg[0].bits.b1
#define KEY2Trg keyTrg[0].bits.b2

#define KEY0RestainTrg keyTrg[1].bits.b0
#define KEY1RestainTrg keyTrg[1].bits.b1
#define KEY2RestainTrg keyTrg[1].bits.b2

#define STARTTrg KEY0Trg
#define STOPTrg KEY1Trg

#define keyNUM 2
#define RESTAIN_TIMES 200  // 200 × 10ms = 2s
/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/*******key***********/
volatile _TKS_FLAGA_type keyTrg[2];
volatile unsigned char k_count[2];
unsigned keyTime[keyNUM] = {0};
/* Public variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
static void keyScan(void);
void testFun(void);
/* Private user code ---------------------------------------------------------*/

/*----------------------------------------------------------------------------
 *      Thread 1 'Thread_Name': Sample thread
 *---------------------------------------------------------------------------*/

void testThread(void const *argument);            // thread function
osThreadId tid_testThread;                        // thread id
osThreadDef(testThread, osPriorityNormal, 1, 0);  // thread object

int Init_testThread(void)
{
    tid_testThread = osThreadCreate(osThread(testThread), NULL);
    if (!tid_testThread)
        return (-1);

    NO1(GPIO_PIN_RESET);
    NO2(GPIO_PIN_RESET);
    NO3(GPIO_PIN_RESET);
    NO4(GPIO_PIN_RESET);
    NO5(GPIO_PIN_RESET);
    NO6(GPIO_PIN_RESET);
    NO7(GPIO_PIN_RESET);
    NO8(GPIO_PIN_RESET);
    return (0);
}

void testThread(void const *argument)
{
    while (1)
    {
        // NO8(GPIO_PIN_RESET);
        // NO8(GPIO_PIN_SET);

        osDelay(10);
        //  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);  // 485_DIR2
        // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);  // 485_DIR2
        // HAL_UART_Transmit_DMA(&huart2, tx2DMAbuffer, strlen((void *)tx2DMAbuffer));
        keyScan();
        testFun();
    }
}

/**
 * @brief
 */
static void keyScan(void)
{
    static uint8_t keyDataBak   = 0;
    static uint8_t keyDataValue = 0;
    unsigned char keyRestain    = 0, keyData, i;

    keyData = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15) | (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) << 1);

    if (keyData != keyDataBak)
    {
        keyDataBak = keyData;
    }
    else
    {
        keyDataValue = keyData;
    }

    keyTrg[0].byte = keyDataValue & (keyDataValue ^ k_count[0]);
    k_count[0]     = keyDataValue;

    for (i = 0; i < keyNUM; i++)
    {
        if (k_count[0] & (1 << i))
        {
            if (keyTime[i] < RESTAIN_TIMES)
                keyTime[i]++;
            else
                keyRestain |= (1 << i);
        }
        else
        {
            // if (keyTime[i] > 0)  // short press
            //     Key_Up_Trg |= (1 << i);
            // else
            //     Key_Up_Trg &= (~(1 << i));

            keyTime[i] = 0;
            keyRestain &= (~(1 << i));
        }
    }
    keyTrg[1].byte = keyRestain & (keyRestain ^ k_count[1]);
    k_count[1]     = keyRestain;
}

void testFun(void)
{
    uint8_t ICT_fsm_state;

    if (STARTTrg)
    {
        l_sys.u8ICT_PowerKey = TRUE;
    }
    if (STOPTrg)
    {
        l_sys.u8ICT_PowerKey = FALSE;
    }
    switch (ICT_fsm_state)
    {
        case ICT_IDLE: {
            if (l_sys.u8ICT_PowerKey == TRUE)  //上电
            {
                g_sys.status.ICT.u16Status = ICT_START;
                g_sys.status.ICT.u16Fsm    = ICT_ST_START;
                l_sys.u8ICT_Delay          = 10;
                l_sys.u8ICT_Start          = TRUE;
                printf("ICT_START\n");

                NO1(0);
                NO2(0);
                NO3(0);
                NO4(0);
                NO5(0);
                NO6(0);
                NO7(0);
                NO8(1);

                ICT_test = 0;
                ICTStep  = 0;

                g_sys.status.ICT.u16Test = 0;
            }
            else
            {
                printf("ICT_Stop\n");
                g_sys.status.ICT.u16Status = ICT_IDLE;
                NO1(0);
                NO2(0);
                NO3(0);
                NO4(0);
                NO5(0);
                NO6(0);
                NO7(0);
                NO8(0);
            }
            break;
        }
        case ICT_START: {
            if (l_sys.u8ICT_Delay)
            {
                l_sys.u8ICT_Delay--;
            }
            else
            {
                /**
                 * clear data;
                 * @brief
                 */
                l_sys.u8ICT_Delay          = 3;  // wait AI ready
                g_sys.status.ICT.u16Status = ICT_TEST;
            }
            break;
        }
        case ICT_TEST: {
            static uint16_t ICTDelay[2] = {0};
        LINE_1:
            if (ICTDelay[0])
            {
                ICTDelay[0]--;
                goto LINE_2;
            }

        LINE_2:
            if (ICTDelay[1])
            {
                ICTDelay[1]--;
                goto ICT_TEST_EXIT;
            }

        ICT_TEST_EXIT:
            break;
        }
        case ICT_STOP:
            break;
    }
}
